package com.fenghuajueli.module_host.utils

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.LogUtils
import com.fenghuajueli.libbasecoreui.baseswitch.GeneratorUtil
import com.fenghuajueli.libbasecoreui.baseswitch.SwitchKeyUtils
import com.fenghuajueli.libbasecoreui.baseswitch.SwitchKeyV4Helper
import com.fenghuajueli.libbasecoreui.constants.AppConfigInfo
import com.fenghuajueli.libbasecoreui.data.adv4.AdV4Type
import com.fenghuajueli.libbasecoreui.listener.BaseCallBackListener
import com.fenghuajueli.module_user.network.repository.RefundRepository
import com.fenghuajueli.module_user.network.repository.TemplateRepository
import com.fenghuajueli.module_user.utils.UserModuleInitUtils
import com.sy.lib_base_ad.IncentiveMode
import com.sy.lib_base_ad.IncentiveModeType
import com.sy.module_ad_switch_manager.AdSwitchManger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope

sealed interface LaunchState {
    data object Default : LaunchState
    data object Success : LaunchState
    data object Fail : LaunchState
}

class LauncherViewModel : ViewModel() {
    private val timestamp: Long by lazy { System.currentTimeMillis() }
    private val nonce: String by lazy { GeneratorUtil.randomSequence(32) }
    private val appId: String by lazy { AppConfigInfo.APPLICATION_ID }
    private val channel: String by lazy { AppConfigInfo.CHANNEL }

    private val _v2Switch = MutableStateFlow<LaunchState>(LaunchState.Default)
    val v2Switch = _v2Switch.asStateFlow()

    private val _v3Switch = MutableStateFlow<LaunchState>(LaunchState.Default)
    val v3Switch = _v3Switch.asStateFlow()

    private val _v4Switch = MutableStateFlow<LaunchState>(LaunchState.Default)
    val v4Switch = _v4Switch.asStateFlow()

    @OptIn(ExperimentalCoroutinesApi::class)
    fun getSwitchKey() = viewModelScope.launch {
        supervisorScope {
            launch {
                v2SwitchKeyFlow()
                    .collect { success ->
                        if (success) {
                            UserModuleInitUtils.updateUserInfoByToken(false)
                            launcherInitData()
                        }
                        _v2Switch.emit(success.returns())
                    }
            }

            launch {
                //从v4接口请求广告配置
                v4SwitchKeyFlow()
                    .combine(v4TopOnKeyFlow()) { getV4KeySuccess, _ ->
                        //这里处理v4逻辑
                        getV4KeySuccess && SwitchKeyV4Helper.calculateAdTypeConfigs.isNotEmpty() && SwitchKeyV4Helper.calculateAdTypeConfigs.find { AdV4Type.adOpenScreenIdType == it.type } != null
                    }
                    .filter { v4Success ->
                        _v4Switch.emit(v4Success.returns())
                        !v4Success
                    }
                    .flatMapConcat {
                        v3SwitchKeyFlow()
                    }
                    .collect { v3Success ->
                        _v3Switch.emit(v3Success.returns())
                    }
            }
        }
    }

    private fun v4TopOnKeyFlow() = callbackFlow {
        val startTime = System.currentTimeMillis()
        LogUtils.d("v4TopOnKey请求开始")
        SwitchKeyUtils.getV4TopOnKey(
            timestamp,
            nonce,
            appId,
            object : BaseCallBackListener<String> {
                override fun onSuccess(data: String) {
                    LogUtils.d("v4TopOnKey请求结束  成功：true  耗时：${System.currentTimeMillis() - startTime}")
                    trySend(true)
                    channel.close()
                }

                override fun onFailed(error: String) {
                    LogUtils.d("v4TopOnKey请求结束  成功：false  耗时：${System.currentTimeMillis() - startTime}  $error")
                    trySend(false)
                    channel.close()
                }

                override fun onHandlerStart() = Unit
            })

        awaitClose {
            LogUtils.d("v4TopOnKeyFlow: 获取v4TopOnKey流关闭")
        }
    }

    private fun v4SwitchKeyFlow() = callbackFlow {
        val startTime = System.currentTimeMillis()
        LogUtils.d("v4开关请求开始")
        SwitchKeyUtils.getV4SwitchKey(
            AppConfigInfo.VERSION_CODE,
            timestamp,
            nonce,
            appId,
            this@LauncherViewModel.channel,
            object : BaseCallBackListener<String> {
                override fun onSuccess(data: String) {
                    LogUtils.d("v4开关请求结束  成功：true  耗时：${System.currentTimeMillis() - startTime}")
                    trySend(true)
                    channel.close()
                }

                override fun onFailed(error: String?) {
                    LogUtils.d("v4开关请求结束  成功：false  耗时：${System.currentTimeMillis() - startTime}    $error")
                    trySend(false)
                    channel.close()
                }

                override fun onHandlerStart() = Unit
            }
        )

        awaitClose {
            LogUtils.d("v4SwitchKeyFlow: 获取v4开关流关闭")
        }
    }

    private fun v3SwitchKeyFlow() = callbackFlow {
        val startTime = System.currentTimeMillis()
        LogUtils.d("v3开关请求开始")
        SwitchKeyUtils.getV3SwitchKey(
            AppConfigInfo.VERSION_CODE,
            timestamp,
            nonce,
            appId,
            this@LauncherViewModel.channel,
            object : BaseCallBackListener<String> {
                override fun onSuccess(data: String) {
                    LogUtils.d("v3开关请求结束  成功：true  耗时：${System.currentTimeMillis() - startTime}")
                    trySend(true)
                    channel.close()
                }

                override fun onFailed(error: String) {
                    LogUtils.d("v3开关请求结束  成功：false  耗时：${System.currentTimeMillis() - startTime}    $error")
                    trySend(false)
                    channel.close()
                }

                override fun onHandlerStart() = Unit
            }
        )

        awaitClose {
            LogUtils.d("v3SwitchKeyFlow: 获取v3开关流关闭")
        }
    }

    private fun v2SwitchKeyFlow() = callbackFlow {
        val startTime = System.currentTimeMillis()
        LogUtils.d("v2开关请求开始")
        //获取v2广告及其他配置。广告配置和v3相互独立，初始化广告是在v3中。
        SwitchKeyUtils.getSwitchKey(
            timestamp,
            nonce,
            appId,
            this@LauncherViewModel.channel,
            object : BaseCallBackListener<String> {
                override fun onSuccess(data: String) {
                    LogUtils.d("v2开关请求结束  成功：true  耗时：${System.currentTimeMillis() - startTime}")
                    trySend(true)
                    channel.close()
                }

                override fun onFailed(error: String) {
                    LogUtils.d("v2开关请求结束  成功：false  耗时：${System.currentTimeMillis() - startTime}    $error")
                    trySend(false)
                    channel.close()
                }

                override fun onHandlerStart() = Unit
            }
        )

        awaitClose {
            LogUtils.d("v2SwitchKeyFlow: 获取v2开关流关闭")
        }
    }

    private fun launcherInitData() = viewModelScope.launch(Dispatchers.Default) {
        getTemplate()
        getRefund()
        initIncentiveMode()
    }

    private suspend fun getTemplate() = coroutineScope {
        TemplateRepository.initTemplateData()
    }

    private suspend fun getRefund() = coroutineScope {
        RefundRepository.initRefundData()
    }

    private suspend fun initIncentiveMode() = coroutineScope {
        val config = SwitchKeyUtils.getIncentiveModeConfig()
        val incentiveModeType = when (config.incentiveSwitch) {
            IncentiveModeType.INCENTIVE_PAY.code -> IncentiveModeType.INCENTIVE_PAY
            IncentiveModeType.INCENTIVE_NO_PAY.code -> IncentiveModeType.INCENTIVE_NO_PAY
            IncentiveModeType.NO_INCENTIVE.code -> IncentiveModeType.NO_INCENTIVE
            else -> IncentiveModeType.NO_INCENTIVE
        }
        val incentiveFreeTimes = config.incentiveTimes.takeIf { it >= 0 } ?: 0
        val incentiveModeSwitch = incentiveModeType != IncentiveModeType.NO_INCENTIVE && incentiveFreeTimes > 0
        AdSwitchManger.incentiveMode = IncentiveMode(
            incentiveModeSwitch = incentiveModeSwitch,
            incentiveModeType = incentiveModeType,
            incentiveFreeTimes = incentiveFreeTimes,
            incentiveStartSwitch = config.incentiveStartSwitch == 1
        )
        LogUtils.d("激励模式参数: ${AdSwitchManger.incentiveMode}")
    }

    override fun onCleared() {
        super.onCleared()
        SwitchKeyV4Helper.calculateAdTypeConfigs.clear()
    }

    private fun Boolean.returns() = if (this) LaunchState.Success else LaunchState.Fail
}
